1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.ComboBox;
26 
27 private import gdk.Device;
28 private import glib.ConstructionException;
29 private import glib.MemorySlice;
30 private import glib.Str;
31 private import glib.c.functions;
32 private import gobject.ObjectG;
33 private import gobject.Signals;
34 private import gtk.CellEditableIF;
35 private import gtk.CellEditableT;
36 private import gtk.CellLayoutIF;
37 private import gtk.CellLayoutT;
38 private import gtk.TreeIter;
39 private import gtk.TreeModelIF;
40 private import gtk.Widget;
41 private import gtk.c.functions;
42 public  import gtk.c.types;
43 private import std.algorithm;
44 
45 
46 /**
47  * A `GtkComboBox` is a widget that allows the user to choose from a list of
48  * valid choices.
49  * 
50  * ![An example GtkComboBox](combo-box.png)
51  * 
52  * The `GtkComboBox` displays the selected choice; when activated, the
53  * `GtkComboBox` displays a popup which allows the user to make a new choice.
54  * 
55  * The `GtkComboBox` uses the model-view pattern; the list of valid choices
56  * is specified in the form of a tree model, and the display of the choices
57  * can be adapted to the data in the model by using cell renderers, as you
58  * would in a tree view. This is possible since `GtkComboBox` implements the
59  * [iface@Gtk.CellLayout] interface. The tree model holding the valid
60  * choices is not restricted to a flat list, it can be a real tree, and the
61  * popup will reflect the tree structure.
62  * 
63  * To allow the user to enter values not in the model, the
64  * [property@Gtk.ComboBox:has-entry] property allows the `GtkComboBox` to
65  * contain a [class@Gtk.Entry]. This entry can be accessed by calling
66  * [method@Gtk.ComboBox.get_child] on the combo box.
67  * 
68  * For a simple list of textual choices, the model-view API of `GtkComboBox`
69  * can be a bit overwhelming. In this case, [class@Gtk.ComboBoxText] offers
70  * a simple alternative. Both `GtkComboBox` and `GtkComboBoxText` can contain
71  * an entry.
72  * 
73  * ## CSS nodes
74  * 
75  * ```
76  * combobox
77  * ├── box.linked
78  * │   ╰── button.combo
79  * │       ╰── box
80  * │           ├── cellview
81  * │           ╰── arrow
82  * ╰── window.popup
83  * ```
84  * 
85  * A normal combobox contains a box with the .linked class, a button
86  * with the .combo class and inside those buttons, there are a cellview and
87  * an arrow.
88  * 
89  * ```
90  * combobox
91  * ├── box.linked
92  * │   ├── entry.combo
93  * │   ╰── button.combo
94  * │       ╰── box
95  * │           ╰── arrow
96  * ╰── window.popup
97  * ```
98  * 
99  * A `GtkComboBox` with an entry has a single CSS node with name combobox.
100  * It contains a box with the .linked class. That box contains an entry and
101  * a button, both with the .combo class added. The button also contains another
102  * node with name arrow.
103  * 
104  * # Accessibility
105  * 
106  * `GtkComboBox` uses the %GTK_ACCESSIBLE_ROLE_COMBO_BOX role.
107  */
108 public class ComboBox : Widget, CellEditableIF, CellLayoutIF
109 {
110 	/** the main Gtk struct */
111 	protected GtkComboBox* gtkComboBox;
112 
113 	/** Get the main Gtk struct */
114 	public GtkComboBox* getComboBoxStruct(bool transferOwnership = false)
115 	{
116 		if (transferOwnership)
117 			ownedRef = false;
118 		return gtkComboBox;
119 	}
120 
121 	/** the main Gtk struct as a void* */
122 	protected override void* getStruct()
123 	{
124 		return cast(void*)gtkComboBox;
125 	}
126 
127 	/**
128 	 * Sets our main struct and passes it to the parent class.
129 	 */
130 	public this (GtkComboBox* gtkComboBox, bool ownedRef = false)
131 	{
132 		this.gtkComboBox = gtkComboBox;
133 		super(cast(GtkWidget*)gtkComboBox, ownedRef);
134 	}
135 
136 	// add the CellEditable capabilities
137 	mixin CellEditableT!(GtkComboBox);
138 
139 	// add the CellLayout capabilities
140 	mixin CellLayoutT!(GtkComboBox);
141 
142 	/**
143 	 * Creates a new empty GtkComboBox.
144 	 * Params:
145 	 *   entry = If true, create an empty ComboBox with an entry.
146 	 * Throws: ConstructionException GTK+ fails to create the object.
147 	 */
148 	public this (bool entry=true)
149 	{
150 		GtkComboBox* __p;
151 		if ( entry )
152 		{
153 			// GtkWidget* gtk_combo_box_new_text (void);
154 			__p = cast(GtkComboBox*)gtk_combo_box_new_with_entry();
155 		}
156 		else
157 		{
158 			// GtkWidget* gtk_combo_box_new (void);
159 			__p = cast(GtkComboBox*)gtk_combo_box_new();
160 		}
161 
162 		if(__p is null)
163 		{
164 			throw new ConstructionException("null returned by gtk_combo_box_new");
165 		}
166 
167 		this(__p);
168 	}
169 
170 
171 	/**
172 	 * Creates a new GtkComboBox with the model initialized to model.
173 	 * Params:
174 	 *   model = A GtkTreeModel.
175 	 *   entry = If true, create an empty ComboBox with an entry.
176 	 * Throws: ConstructionException GTK+ fails to create the object.
177 	 */
178 	public this (TreeModelIF model, bool entry=true)
179 	{
180 		GtkComboBox* __p;
181 		if ( entry )
182 		{
183 			// GtkWidget* gtk_combo_box_new_with_model_and_entry (GtkTreeModel *model);
184 			__p = cast(GtkComboBox*)gtk_combo_box_new_with_model_and_entry((model is null) ? null : model.getTreeModelStruct());
185 		}
186 		else
187 		{
188 			// GtkWidget* gtk_combo_box_new_with_model (GtkTreeModel *model);
189 			__p = cast(GtkComboBox*)gtk_combo_box_new_with_model((model is null) ? null : model.getTreeModelStruct());
190 		}
191 
192 		if(__p is null)
193 		{
194 			throw new ConstructionException("null returned by gtk_combo_box_new");
195 		}
196 
197 		this(__p);
198 	}
199 
200 	/**
201 	 */
202 
203 	/** */
204 	public static GType getType()
205 	{
206 		return gtk_combo_box_get_type();
207 	}
208 
209 	/**
210 	 * Returns the index of the currently active item.
211 	 *
212 	 * If the model is a non-flat treemodel, and the active item is not
213 	 * an immediate child of the root of the tree, this function returns
214 	 * `gtk_tree_path_get_indices (path)[0]`, where `path` is the
215 	 * [struct@Gtk.TreePath] of the active item.
216 	 *
217 	 * Returns: An integer which is the index of the currently active item,
218 	 *     or -1 if there’s no active item
219 	 */
220 	public int getActive()
221 	{
222 		return gtk_combo_box_get_active(gtkComboBox);
223 	}
224 
225 	/**
226 	 * Returns the ID of the active row of @combo_box.
227 	 *
228 	 * This value is taken from the active row and the column specified
229 	 * by the [property@Gtk.ComboBox:id-column] property of @combo_box
230 	 * (see [method@Gtk.ComboBox.set_id_column]).
231 	 *
232 	 * The returned value is an interned string which means that you can
233 	 * compare the pointer by value to other interned strings and that you
234 	 * must not free it.
235 	 *
236 	 * If the [property@Gtk.ComboBox:id-column] property of @combo_box is
237 	 * not set, or if no row is active, or if the active row has a %NULL
238 	 * ID value, then %NULL is returned.
239 	 *
240 	 * Returns: the ID of the active row
241 	 */
242 	public string getActiveId()
243 	{
244 		return Str.toString(gtk_combo_box_get_active_id(gtkComboBox));
245 	}
246 
247 	/**
248 	 * Sets @iter to point to the currently active item.
249 	 *
250 	 * If no item is active, @iter is left unchanged.
251 	 *
252 	 * Params:
253 	 *     iter = A `GtkTreeIter`
254 	 *
255 	 * Returns: %TRUE if @iter was set, %FALSE otherwise
256 	 */
257 	public bool getActiveIter(out TreeIter iter)
258 	{
259 		GtkTreeIter* outiter = sliceNew!GtkTreeIter();
260 
261 		auto __p = gtk_combo_box_get_active_iter(gtkComboBox, outiter) != 0;
262 
263 		iter = ObjectG.getDObject!(TreeIter)(outiter, true);
264 
265 		return __p;
266 	}
267 
268 	/**
269 	 * Returns whether the combo box sets the dropdown button
270 	 * sensitive or not when there are no items in the model.
271 	 *
272 	 * Returns: %GTK_SENSITIVITY_ON if the dropdown button
273 	 *     is sensitive when the model is empty, %GTK_SENSITIVITY_OFF
274 	 *     if the button is always insensitive or %GTK_SENSITIVITY_AUTO
275 	 *     if it is only sensitive as long as the model has one item to
276 	 *     be selected.
277 	 */
278 	public GtkSensitivityType getButtonSensitivity()
279 	{
280 		return gtk_combo_box_get_button_sensitivity(gtkComboBox);
281 	}
282 
283 	/**
284 	 * Gets the child widget of @combo_box.
285 	 *
286 	 * Returns: the child widget of @combo_box
287 	 */
288 	public Widget getChild()
289 	{
290 		auto __p = gtk_combo_box_get_child(gtkComboBox);
291 
292 		if(__p is null)
293 		{
294 			return null;
295 		}
296 
297 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) __p);
298 	}
299 
300 	/**
301 	 * Returns the column which @combo_box is using to get the strings
302 	 * from to display in the internal entry.
303 	 *
304 	 * Returns: A column in the data source model of @combo_box.
305 	 */
306 	public int getEntryTextColumn()
307 	{
308 		return gtk_combo_box_get_entry_text_column(gtkComboBox);
309 	}
310 
311 	/**
312 	 * Returns whether the combo box has an entry.
313 	 *
314 	 * Returns: whether there is an entry in @combo_box.
315 	 */
316 	public bool getHasEntry()
317 	{
318 		return gtk_combo_box_get_has_entry(gtkComboBox) != 0;
319 	}
320 
321 	/**
322 	 * Returns the column which @combo_box is using to get string IDs
323 	 * for values from.
324 	 *
325 	 * Returns: A column in the data source model of @combo_box.
326 	 */
327 	public int getIdColumn()
328 	{
329 		return gtk_combo_box_get_id_column(gtkComboBox);
330 	}
331 
332 	/**
333 	 * Returns the `GtkTreeModel` of @combo_box.
334 	 *
335 	 * Returns: A `GtkTreeModel` which was passed
336 	 *     during construction.
337 	 */
338 	public TreeModelIF getModel()
339 	{
340 		auto __p = gtk_combo_box_get_model(gtkComboBox);
341 
342 		if(__p is null)
343 		{
344 			return null;
345 		}
346 
347 		return ObjectG.getDObject!(TreeModelIF)(cast(GtkTreeModel*) __p);
348 	}
349 
350 	/**
351 	 * Gets whether the popup uses a fixed width.
352 	 *
353 	 * Returns: %TRUE if the popup uses a fixed width
354 	 */
355 	public bool getPopupFixedWidth()
356 	{
357 		return gtk_combo_box_get_popup_fixed_width(gtkComboBox) != 0;
358 	}
359 
360 	/**
361 	 * Returns the current row separator function.
362 	 *
363 	 * Returns: the current row separator function.
364 	 */
365 	public GtkTreeViewRowSeparatorFunc getRowSeparatorFunc()
366 	{
367 		return gtk_combo_box_get_row_separator_func(gtkComboBox);
368 	}
369 
370 	/**
371 	 * Hides the menu or dropdown list of @combo_box.
372 	 *
373 	 * This function is mostly intended for use by accessibility technologies;
374 	 * applications should have little use for it.
375 	 */
376 	public void popdown()
377 	{
378 		gtk_combo_box_popdown(gtkComboBox);
379 	}
380 
381 	/**
382 	 * Pops up the menu or dropdown list of @combo_box.
383 	 *
384 	 * This function is mostly intended for use by accessibility technologies;
385 	 * applications should have little use for it.
386 	 *
387 	 * Before calling this, @combo_box must be mapped, or nothing will happen.
388 	 */
389 	public void popup()
390 	{
391 		gtk_combo_box_popup(gtkComboBox);
392 	}
393 
394 	/**
395 	 * Pops up the menu of @combo_box.
396 	 *
397 	 * Note that currently this does not do anything with the device, as it was
398 	 * previously only used for list-mode combo boxes, and those were removed
399 	 * in GTK 4. However, it is retained in case similar functionality is added
400 	 * back later.
401 	 *
402 	 * Params:
403 	 *     device = a `GdkDevice`
404 	 */
405 	public void popupForDevice(Device device)
406 	{
407 		gtk_combo_box_popup_for_device(gtkComboBox, (device is null) ? null : device.getDeviceStruct());
408 	}
409 
410 	/**
411 	 * Sets the active item of @combo_box to be the item at @index.
412 	 *
413 	 * Params:
414 	 *     index = An index in the model passed during construction,
415 	 *         or -1 to have no active item
416 	 */
417 	public void setActive(int index)
418 	{
419 		gtk_combo_box_set_active(gtkComboBox, index);
420 	}
421 
422 	/**
423 	 * Changes the active row of @combo_box to the one that has an ID equal to
424 	 * @active_id.
425 	 *
426 	 * If @active_id is %NULL, the active row is unset. Rows having
427 	 * a %NULL ID string cannot be made active by this function.
428 	 *
429 	 * If the [property@Gtk.ComboBox:id-column] property of @combo_box is
430 	 * unset or if no row has the given ID then the function does nothing
431 	 * and returns %FALSE.
432 	 *
433 	 * Params:
434 	 *     activeId = the ID of the row to select
435 	 *
436 	 * Returns: %TRUE if a row with a matching ID was found. If a %NULL
437 	 *     @active_id was given to unset the active row, the function
438 	 *     always returns %TRUE.
439 	 */
440 	public bool setActiveId(string activeId)
441 	{
442 		return gtk_combo_box_set_active_id(gtkComboBox, Str.toStringz(activeId)) != 0;
443 	}
444 
445 	/**
446 	 * Sets the current active item to be the one referenced by @iter.
447 	 *
448 	 * If @iter is %NULL, the active item is unset.
449 	 *
450 	 * Params:
451 	 *     iter = The `GtkTreeIter`
452 	 */
453 	public void setActiveIter(TreeIter iter)
454 	{
455 		gtk_combo_box_set_active_iter(gtkComboBox, (iter is null) ? null : iter.getTreeIterStruct());
456 	}
457 
458 	/**
459 	 * Sets whether the dropdown button of the combo box should update
460 	 * its sensitivity depending on the model contents.
461 	 *
462 	 * Params:
463 	 *     sensitivity = specify the sensitivity of the dropdown button
464 	 */
465 	public void setButtonSensitivity(GtkSensitivityType sensitivity)
466 	{
467 		gtk_combo_box_set_button_sensitivity(gtkComboBox, sensitivity);
468 	}
469 
470 	/**
471 	 * Sets the child widget of @combo_box.
472 	 *
473 	 * Params:
474 	 *     child = the child widget
475 	 */
476 	public void setChild(Widget child)
477 	{
478 		gtk_combo_box_set_child(gtkComboBox, (child is null) ? null : child.getWidgetStruct());
479 	}
480 
481 	/**
482 	 * Sets the model column which @combo_box should use to get strings
483 	 * from to be @text_column.
484 	 *
485 	 * For this column no separate
486 	 * [class@Gtk.CellRenderer] is needed.
487 	 *
488 	 * The column @text_column in the model of @combo_box must be of
489 	 * type %G_TYPE_STRING.
490 	 *
491 	 * This is only relevant if @combo_box has been created with
492 	 * [property@Gtk.ComboBox:has-entry] as %TRUE.
493 	 *
494 	 * Params:
495 	 *     textColumn = A column in @model to get the strings from for
496 	 *         the internal entry
497 	 */
498 	public void setEntryTextColumn(int textColumn)
499 	{
500 		gtk_combo_box_set_entry_text_column(gtkComboBox, textColumn);
501 	}
502 
503 	/**
504 	 * Sets the model column which @combo_box should use to get string IDs
505 	 * for values from.
506 	 *
507 	 * The column @id_column in the model of @combo_box must be of type
508 	 * %G_TYPE_STRING.
509 	 *
510 	 * Params:
511 	 *     idColumn = A column in @model to get string IDs for values from
512 	 */
513 	public void setIdColumn(int idColumn)
514 	{
515 		gtk_combo_box_set_id_column(gtkComboBox, idColumn);
516 	}
517 
518 	/**
519 	 * Sets the model used by @combo_box to be @model.
520 	 *
521 	 * Will unset a previously set model (if applicable). If model is %NULL,
522 	 * then it will unset the model.
523 	 *
524 	 * Note that this function does not clear the cell renderers, you have to
525 	 * call [method@Gtk.CellLayout.clear] yourself if you need to set up different
526 	 * cell renderers for the new model.
527 	 *
528 	 * Params:
529 	 *     model = A `GtkTreeModel`
530 	 */
531 	public void setModel(TreeModelIF model)
532 	{
533 		gtk_combo_box_set_model(gtkComboBox, (model is null) ? null : model.getTreeModelStruct());
534 	}
535 
536 	/**
537 	 * Specifies whether the popup’s width should be a fixed width.
538 	 *
539 	 * If @fixed is %TRUE, the popup's width is set to match the
540 	 * allocated width of the combo box.
541 	 *
542 	 * Params:
543 	 *     fixed = whether to use a fixed popup width
544 	 */
545 	public void setPopupFixedWidth(bool fixed)
546 	{
547 		gtk_combo_box_set_popup_fixed_width(gtkComboBox, fixed);
548 	}
549 
550 	/**
551 	 * Sets the row separator function, which is used to determine
552 	 * whether a row should be drawn as a separator.
553 	 *
554 	 * If the row separator function is %NULL, no separators are drawn.
555 	 * This is the default value.
556 	 *
557 	 * Params:
558 	 *     func = a `GtkTreeViewRowSeparatorFunc`
559 	 *     data = user data to pass to @func
560 	 *     destroy = destroy notifier for @data
561 	 */
562 	public void setRowSeparatorFunc(GtkTreeViewRowSeparatorFunc func, void* data, GDestroyNotify destroy)
563 	{
564 		gtk_combo_box_set_row_separator_func(gtkComboBox, func, data, destroy);
565 	}
566 
567 	/**
568 	 * Emitted to when the combo box is activated.
569 	 *
570 	 * The `::activate` signal on `GtkComboBox` is an action signal and
571 	 * emitting it causes the combo box to pop up its dropdown.
572 	 *
573 	 * Since: 4.6
574 	 */
575 	gulong addOnActivate(void delegate(ComboBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
576 	{
577 		return Signals.connect(this, "activate", dlg, connectFlags ^ ConnectFlags.SWAPPED);
578 	}
579 
580 	/**
581 	 * Emitted when the active item is changed.
582 	 *
583 	 * The can be due to the user selecting a different item from the list,
584 	 * or due to a call to [method@Gtk.ComboBox.set_active_iter]. It will
585 	 * also be emitted while typing into the entry of a combo box with an entry.
586 	 */
587 	gulong addOnChanged(void delegate(ComboBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
588 	{
589 		return Signals.connect(this, "changed", dlg, connectFlags ^ ConnectFlags.SWAPPED);
590 	}
591 
592 	/**
593 	 * Emitted to allow changing how the text in a combo box's entry is displayed.
594 	 *
595 	 * See [property@Gtk.ComboBox:has-entry].
596 	 *
597 	 * Connect a signal handler which returns an allocated string representing
598 	 * @path. That string will then be used to set the text in the combo box's
599 	 * entry. The default signal handler uses the text from the
600 	 * [property@Gtk.ComboBox:entry-text-column] model column.
601 	 *
602 	 * Here's an example signal handler which fetches data from the model and
603 	 * displays it in the entry.
604 	 * ```c
605 	 * static char *
606 	 * format_entry_text_callback (GtkComboBox *combo,
607 	 * const char *path,
608 	 * gpointer     user_data)
609 	 * {
610 	 * GtkTreeIter iter;
611 	 * GtkTreeModel model;
612 	 * double       value;
613 	 *
614 	 * model = gtk_combo_box_get_model (combo);
615 	 *
616 	 * gtk_tree_model_get_iter_from_string (model, &iter, path);
617 	 * gtk_tree_model_get (model, &iter,
618 	 * THE_DOUBLE_VALUE_COLUMN, &value,
619 	 * -1);
620 	 *
621 	 * return g_strdup_printf ("%g", value);
622 	 * }
623 	 * ```
624 	 *
625 	 * Params:
626 	 *     path = the [struct@Gtk.TreePath] string from the combo box's current model
627 	 *         to format text for
628 	 *
629 	 * Returns: a newly allocated string representing @path
630 	 *     for the current `GtkComboBox` model.
631 	 */
632 	gulong addOnFormatEntryText(string delegate(string, ComboBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
633 	{
634 		return Signals.connect(this, "format-entry-text", dlg, connectFlags ^ ConnectFlags.SWAPPED);
635 	}
636 
637 	/**
638 	 * Emitted to move the active selection.
639 	 *
640 	 * This is an [keybinding signal](class.SignalAction.html).
641 	 *
642 	 * Params:
643 	 *     scrollType = a `GtkScrollType`
644 	 */
645 	gulong addOnMoveActive(void delegate(GtkScrollType, ComboBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
646 	{
647 		return Signals.connect(this, "move-active", dlg, connectFlags ^ ConnectFlags.SWAPPED);
648 	}
649 
650 	/**
651 	 * Emitted to popdown the combo box list.
652 	 *
653 	 * This is an [keybinding signal](class.SignalAction.html).
654 	 *
655 	 * The default bindings for this signal are Alt+Up and Escape.
656 	 */
657 	gulong addOnPopdown(bool delegate(ComboBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
658 	{
659 		return Signals.connect(this, "popdown", dlg, connectFlags ^ ConnectFlags.SWAPPED);
660 	}
661 
662 	/**
663 	 * Emitted to popup the combo box list.
664 	 *
665 	 * This is an [keybinding signal](class.SignalAction.html).
666 	 *
667 	 * The default binding for this signal is Alt+Down.
668 	 */
669 	gulong addOnPopup(void delegate(ComboBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
670 	{
671 		return Signals.connect(this, "popup", dlg, connectFlags ^ ConnectFlags.SWAPPED);
672 	}
673 }